#!/usr/bin/python
# -*- coding: UTF-8 -*-
import socket
import struct
import os
import sys
import argparse
import time

def mkdir(path):
    # 去除首位空格
    path=path.strip()
    # 去除尾部 \ 符号
    path=path.rstrip("\\")

    # 判断路径是否存在
    # 存在     True
    # 不存在   False
    isExists=os.path.exists(path)

    # 判断结果
    if not isExists:
        # 如果不存在则创建目录
        os.makedirs(path)
        print('[Info] : ' + path + ' created')
    else:
        # 如果目录存在则不创建，并提示目录已存在
        print('[Info] : ' + path+' already exist')
    return path

def mklogfile(path):
    logpath = path
    for name in range(1,999999):
        logname = path + '/' + str(name) + '.dat'
        if not os.path.isfile(logname):
            data_file = open(logname, 'wb+')
            print("[Info] : Log file open successfully :" + logname)
            return data_file

def logger(arg):

    # 设置log日志存储位置
    logpath = arg.log
    listenport = arg.port
    ipaddress = arg.ip
    mkdir(logpath)
    data = mklogfile(logpath)

    # 创建套接字，尝试连接主机
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 绑定一个本地信息
    bindaddr = ('', listenport)
    udp_socket.bind(bindaddr)
    udp_socket.settimeout(3)
    totalMb = 0;
    cycleTime = time.time()
    turnonServer = bytes([0xfe,0x03,0x00,0x00,0x00,0xac,0x0b,0x00,0x00,0xa0,0x28])
    connaddr = (ipaddress,listenport)
    # 如果连接成功
    while True:

        try:
            # 接收数据
            recv_data = udp_socket.recvfrom(1024)
            if len(recv_data) > 0:
                # recv_data是一个元组(接收到的数据)
                # 存储接收到的数据
                recv_msg = recv_data[0]

                # 接收到数据的个数
                recvbytes = len(recv_msg)
                totalMb+= recvbytes/1048576
                # 打印收到的消息
                sys.stdout.write("Recv:%dbytes Total:%fMb" %(recvbytes,totalMb));
                sys.stdout.write("\r");
                sys.stdout.flush();

                # 保存数据到数据库
                data.write(struct.pack('B'*len(recv_msg), *recv_msg))

                # 5s自动发送心跳指令，保持连接服务器
                if (time.time() - cycleTime) > 1:
                    udp_socket.sendto(turnonServer,connaddr)
                    cycleTime = time.time()


            else:
                print('[Error] : No data input')

        except socket.timeout:
            # 自动发送连接指令，尝试连接服务器
            udp_socket.sendto(turnonServer,connaddr)
            print("[Timeout] : Automatic connect server...")

        finally:
            pass

    udp_socket.close()
    print("[Info] : Close the socket")

def server(arg):

    # 设置log日志存储位置
    logfile = arg.log
    listenport = arg.port
    ipaddress = arg.ip

    # 创建套接字，尝试连接主机
    udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定一个本地信息
    bindaddr = ('', listenport)
    udp_server.bind(bindaddr)
    linkList = [0]
    # 如果连接成功
    while True:
        data, client = udp_server.recvfrom(1024)
        if linkList.count(client[0]):
            continue
        else:
            linkList.append(client[0])
            addr = (client[0],listenport)
        pid = os.fork()
        if pid:
            conn = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            conn.connect(addr)
            print("[INFO]: Cnonnectd:%s"%str(addr))
            dat = open(args.log, 'rb')
            totalSize = os.path.getsize(args.log)
            print("[INFO]: The dat file totalo size: %d bytes"%totalSize)
            while totalSize >0:
                bytes = dat.read(100)
                nbytes = conn.send(bytes)
                totalSize -= nbytes
                # 打印收到的消息
                sys.stdout.write("RemainSize:%d" %totalSize)
                sys.stdout.write("\r")
                sys.stdout.flush()
                time.sleep(0.005)
        else:
            continue

    udp_server.close()
    print("[Info] : Close the server")

def client(arg):

    # 设置log日志存储位置
    logfile = arg.log
    remoteport = arg.port
    remoteaddr = arg.ip

    # 创建套接字，尝试连接主机
    udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    remote_server = (remoteaddr, remoteport)
    try:
        print("[INFO]: Cnonnectd:%s"%str(remoteaddr))
        dat = open(args.log, 'rb')
        totalSize = os.path.getsize(args.log)
        print("[INFO]: The dat file totalo size: %d bytes"%totalSize)
        while totalSize >0:
            bytes = dat.read(100)
            nbytes =  udp_client.sendto(bytes, remote_server)
            totalSize -= nbytes
            # 打印收到的消息
            sys.stdout.write("RemainSize:%d" %totalSize)
            sys.stdout.write("\r")
            sys.stdout.flush()
            time.sleep(0.005)

    finally:
        print('closing socket')
        udp_client.close()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='manual to this script')
    parser.add_argument("--mode", type=str, default="logger")
    parser.add_argument("--log", type=str, default=os.environ['HOME']+"/mavlog")
    parser.add_argument("--ip", type=str, default="127.0.0.1")
    parser.add_argument("--port", type=int, default=14550)
    args = parser.parse_args()
    print("-------------------------------------")
    print("--WorkMode:%s"%args.mode)
    print("--LogPath :%s"%args.log)
    print("--IP      :%s"%args.ip)
    print("--Port    :%d"%args.port)
    print("-------------------------------------")
    if args.mode == "logger":
        logger(args)
    elif  args.mode == "server":
        server(args)
    elif  args.mode == "client":
        client(args)
    else:
        print("[ERROR]: Invalid work mode:%s"%args.mode)
